package capaNegocio;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.TreeMap;

import org.openstreetmap.gui.jmapviewer.Coordinate;

import tsp.Algoritmo;
import tsp.Instancia;
import tsp.Recorrido;

import capaGrafica.Fecha;


public class Inteligencia implements Serializable
{
	
	private static final long serialVersionUID = 1L;
	private static double idCliente ;
	private static PedidoCliente puntoPartida;
	private static ArrayList<PedidoCliente> listaPedidos;
	private static TreeMap<Integer, PedidoCliente> indicePedido;

	public Inteligencia ()
	{
		listaPedidos= new ArrayList<PedidoCliente>();
		idCliente= 0;
		puntoPartida= new PedidoCliente("Facultad (Punto Partida)", new Coordinate(-34.52225714792779, -58.699607849121094), new Fecha (1,1,1));
		indicePedido= new TreeMap<Integer, PedidoCliente>();
	}

	public static void cargaInicial()
	{
		Inteligencia nueva= new Inteligencia();
	}
	
	public static ArrayList<PedidoCliente> damePedidosDeLaFechaOrdenados (Fecha fecha)
	{
		ArrayList<PedidoCliente> pedidos = damePedidosFecha(fecha);
		cargarTreeMap (pedidos);
		ArrayList<Double> distancias= calcularDistancias(pedidos);
		Recorrido optimo= dameElMejorRecorrido(distancias, pedidos.size());
		ArrayList<PedidoCliente> laMejorListaPedidos= dameMejorListaOrdenada(optimo);
		return laMejorListaPedidos;
	}
	
	public static ArrayList<PedidoCliente> damePedidosFecha(Fecha fecha) 
	{
		ArrayList<PedidoCliente> pedidos= new ArrayList<PedidoCliente>();
		
		for (PedidoCliente e: listaPedidos)
			if (e.getFecha().equals(fecha))
				pedidos.add(e);
		if(!pedidos.contains(puntoPartida))
			pedidos.add(puntoPartida);
		
		return pedidos;
	}
	
	public static void cargarTreeMap (ArrayList <PedidoCliente> pedidosDelDia)
	{
		for (int i= 0; i< pedidosDelDia.size(); i++)
		{
			indicePedido.put((Integer)i, pedidosDelDia.get(i));
		}
	}
	
	public static ArrayList<Double> calcularDistancias(ArrayList<PedidoCliente> pedidos) 
	{
		ArrayList<Double> distanciasEntrePedidosCliente= new ArrayList<Double>();
		int k= 0;
		for (int i= 0 ; i< pedidos.size()-1; i++)
		{
			for (int j= i+1 ; j< pedidos.size(); j++)
			{
				distanciasEntrePedidosCliente.add((double)i);
				distanciasEntrePedidosCliente.add((double)j);
				distanciasEntrePedidosCliente.add(PedidoCliente.distanciaEntrePedidos(pedidos.get(i),pedidos.get(j)));
			}
		}
		return distanciasEntrePedidosCliente;	
	}
	
	public static Recorrido dameElMejorRecorrido (ArrayList<Double> distanciasEntreClientes, int cantPedidos)
	{
		Instancia nueva= new Instancia (distanciasEntreClientes, cantPedidos);
		Recorrido optimo= Algoritmo.resolver(nueva);
		return optimo;
	}
	
	public static ArrayList<PedidoCliente> dameMejorListaOrdenada(Recorrido elMejor)
	{
		ArrayList<PedidoCliente> pedidosOrdenados= new ArrayList<PedidoCliente>();
		ArrayList<Integer> ciudades= elMejor.getCiudades();
		for (int i=0; i< elMejor.size(); i++)
		{	
			PedidoCliente existente = getIndicePedido().get(ciudades.get(i));
			pedidosOrdenados.add(existente);
		}
		return pedidosOrdenados;
	}
	
	public static TreeMap<Integer, PedidoCliente> getIndicePedido() 
	{
		return indicePedido;
	}
	
	public static void agregarPedido (PedidoCliente nuevoPedido)
	{
		if (!listaPedidos.contains(nuevoPedido))
			listaPedidos.add(nuevoPedido);
	}
	
	public void eliminarPedido (PedidoCliente Pedido)
	{
		if (listaPedidos.contains(Pedido))
			listaPedidos.remove(Pedido);
	}	

	public static void setIdCliente() 
	{
		idCliente ++;
	}

	public static double getIdCliente() 
	{
		return idCliente;
	}

	public static ArrayList<PedidoCliente> getListaPedidos() 
	{
		return listaPedidos;
	}
	
	@Override
	public String toString() 
	{
		return "Lista de Pedidos [ "+ listaPedidos + "]";
	}
	
	/*public static void main(String[] args) 
	{
		
		Coordinate coord1= new Coordinate(0,0);
		Coordinate coord2= new Coordinate(-34, -34);
		Coordinate coord3= new Coordinate (10,10);
		Coordinate coord4= new Coordinate (-54,-54);
		Fecha diaDeHoy= new Fecha(2014, 11, 22);
		
		PedidoCliente nuevo1 = new PedidoCliente("0", coord1, diaDeHoy);
		PedidoCliente nuevo2 = new PedidoCliente("1", coord2, diaDeHoy);
		PedidoCliente nuevo3 = new PedidoCliente("2", coord3, diaDeHoy);
		PedidoCliente nuevo4 = new PedidoCliente("3", coord4, diaDeHoy);
		
		Inteligencia prueba= new Inteligencia();
		
		
		Inteligencia.agregarPedido(nuevo1);
		Inteligencia.agregarPedido(nuevo2);
		Inteligencia.agregarPedido(nuevo3);
		Inteligencia.agregarPedido(nuevo4);
		
		System.out.println(damePedidosDeLaFechaOrdenados(diaDeHoy));
		
		
		
		cargarTreeMap(prueba.listaPedidos);
		
		ArrayList <Double> distanciasEntreClientes= calcularDistancias(prueba.listaPedidos);
		
		
		Instancia nueva= new Instancia (distanciasEntreClientes, prueba.listaPedidos.size());
		Recorrido optimo= Algoritmo.resolver(nueva);
		System.out.println("matriz "+optimo);
		
		
		
		ArrayList<PedidoCliente> hojaDeRuta= new ArrayList<PedidoCliente>();
		for (int i=0; i< optimo.size(); i++){
			PedidoCliente existente = prueba.getIndicePedido().get((Integer)i);
			hojaDeRuta.add(existente);
		}
		
		System.out.println(hojaDeRuta);
		
		
	}*/
	
	
}
